---
title: 'Keyboard Interaction'
---

The grid responds to keyboard interactions from the user as well as emitting events when key presses happen on the grid cells. Below shows all the keyboards interactions that can be done with the grid.

## Navigation

Use the arrow keys ({% kbd "←" /%} {% kbd "↑" /%} {% kbd "→" /%} {% kbd "↓" /%}) to move focus up, down, left and right. If the focused cell is already on the boundary for that position (e.g. if on the first column and the left key is pressed) then the key press has no effect. Use {% kbd "^ Ctrl" /%}+{% kbd "←" /%} to move to the start of the line, and {% kbd "^ Ctrl" /%}+{% kbd "→" /%} to move to the end.

If a cell on the first grid row is focused and you press {% kbd "↑" /%}, the focus will be moved into the grid header. The header navigation focus navigation works the same as the grid's: arrows will move up/down/left/right, {% kbd "⇥ Tab" /%} will move the focus horizontally until the last header cell and then move on to the next row.

Use {% kbd "Page Up" /%} and {% kbd "Page Down" /%} to move the scroll up and down by one page. Use {% kbd "Home" /%} and {% kbd "End" /%} to go to the first and last rows.

{% note %}
When a header cell is focused, commands like {% kbd "Page Up" /%}, {% kbd "Page Down" /%}, {% kbd "Home" /%}, {% kbd "End" /%}, {% kbd "^ Ctrl" /%}+{% kbd "←" /%}/{% kbd "→" /%} will not work as they do when a grid cell is focused.
{% /note %}

## Groups

If on a group element, hitting the {% kbd "↵ Enter" /%} key will expand or collapse the group.

## Editing

Pressing the {% kbd "F2" /%} or {% kbd "↵ Enter" /%} key on a cell will put the cell into edit mode, if editing is allowed on the cell. This will work for the default cell editor.

Pressing {% kbd "^ Ctrl" /%}+{% kbd "↵ Enter" /%} keys when selecting a cell range and editing one of the cells, sets the new value of the edited cell to all the editable cells in the selected range

## Selection

Pressing the {% kbd "␣ Space" /%} key when focusing a cell will select the cell's row, or deselect the row if already selected. If multi-select is enabled, this selection change will not remove any previous selections.

## Suppress Focus

If you want keyboard navigation turned off, there are two properties that need to be turned off.

### Suppress Cell Focus

Set `suppressCellFocus=true` in the gridOptions, and Grid Cell Focus will be disabled.

### Suppress Header Focus

Set `suppressHeaderFocus=true` in the gridOptions, and Grid Header Focus will be disabled.

## Column Header Navigation

The grid header supports full keyboard navigation, however the behaviour may differ based on the type of Column Header that is currently focused.

Column Headers can be:

-   Moved by pressing {% kbd "⇧ Shift" /%} + {% kbd "←" /%} / {% kbd "→" /%}.
-   Resized by pressing {% kbd "⌥ Alt" /%} + {% kbd "←" /%} / {% kbd "→" /%}.

### Column Group Headers

While navigating Column Groups Headers, you can do the following:

- If the current Column Group is expandable, pressing {% kbd "↵ Enter" /%} will toggle the expanded state of the group.
- When [Column Cell Selection](./cell-selection/#selecting-cells-via-column-headers) is enabled:
    - If the current Column Group is expandable, pressing {% kbd "⌥ Alt" /%}+{% kbd "↵ Enter" /%} will toggle the expanded state of the group.
    - Press {% kbd "↵ Enter" /%} to select all visible cells in child columns of the focused column group.
    - Press {% kbd "^ Ctrl" /%}+{% kbd "↵ Enter" /%} to select all visible cells in child columns of the focused column group without clearing existing cell ranges.
    - Press {% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to select all cells in visible child columns between the previously selected column group and the focused column group.
    - Press {% kbd "^ Ctrl" /%}+{% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to select all cells in visible child columns between the previously selected column group and the focused column group, without clearing existing cell ranges.

### Normal Column Headers

Regular Column Headers may have selection checkboxes, sorting functions and menus, so to access all these functions while focusing a Column Header, you can do the following:

- Press {% kbd "␣ Space" /%} to toggle the Column Header checkbox selection.
- Press {% kbd "↵ Enter" /%} to toggle the sorting state of that column.
- Press {% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to toggle multi-sort for that column.
- Press {% kbd "⌥ Alt" /%}+{% kbd "↓" /%} to open the menu for the focused Column Header.
- Press {% kbd "^ Ctrl" /%}+{% kbd "↵ Enter" /%} to either open the filter for the focused Column Header (if `columnMenu = 'new'` - default behaviour) or open the menu for the focused Column Header (if `columnMenu = 'legacy'`).
- When a menu is open, simply press {% kbd "⎋ Esc" /%} to close it and the focus will return to the Column Header.
- When [Column Cell Selection](./cell-selection/#selecting-cells-via-column-headers) is enabled:
    - Press {% kbd "↵ Enter" /%} to select all visible cells in the focused column.
    - Press {% kbd "^ Ctrl" /%}+{% kbd "↵ Enter" /%} to select all visible cells in the focused column without clearing existing cell ranges.
    - Press {% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to select all cells in visible columns between the previously selected column and the focused column.
    - Press {% kbd "^ Ctrl" /%}+{% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to select all cells in visible columns between the previously selected column and the focused column without clearing existing cell ranges.
    - Press {% kbd "⌥ Alt" /%}+{% kbd "↵ Enter" /%} to toggle the sorting state of that column.
    - Press {% kbd "⌥ Alt" /%}+{% kbd "⇧ Shift" /%}+{% kbd "↵ Enter" /%} to toggle multi-sort for that column.

### Floating Filter Headers

While navigating the Floating Filter Columns Headers with the keyboard, pressing {% kbd "←" /%} {% kbd "→" /%} will move focus from one Column Header to the next. If you wish to navigate within the Floating Filter Cell, press {% kbd "↵ Enter" /%} to focus the first enabled element within the current Floating Filter Cell, and press {% kbd "⎋ Esc" /%} to return focus to the Floating Filter Column Header.

## Example

The example below has grouped headers, headers and floating filters to demonstrate the features mentioned above:

{% gridExampleRunner title="Keyboard Navigation" name="grid-keyboard-navigation" /%}

## Custom Navigation

Most people will be happy with the default navigation the grid does when you use the arrow keys and the {% kbd "⇥ Tab" /%} key. Some people will want to override this (e.g. you may want the {% kbd "⇥ Tab" /%} key to navigate to the cell below, not the cell to the right). To facilitate this, the grid offers four methods: `navigateToNextCell`, `tabToNextCell`, `navigateToNextHeader` and `tabToNextHeader`.

{% apiDocumentation source="grid-options/properties.json" section="nav" names=["focusGridInnerElement", "navigateToNextCell", "tabToNextCell", "navigateToNextHeader", "tabToNextHeader"] /%}

{% note %}
The `navigateToNextCell` and `tabToNextCell` are only called while navigating across grid cells, while
`navigateToNextHeader` and `tabToNextHeader` are only called while navigating across grid headers.
If you need to navigate from one container to another, pass `rowIndex: -1` in `CellPosition`
or `headerRowIndex: -1` in `HeaderPosition`.
{% /note %}

## Example Custom Cell Navigation

The example below shows how to use `navigateToNextCell`, `tabToNextCell`, `navigateToNextHeader` and `tabToNextHeader` in practice.

Note the following:

-   `navigateToNextCell` swaps the up and down arrow keys.
-   `tabToNextCell` uses tabbing to go up and down rather than right and left.
-   `navigateToNextHeader` swaps the up and down arrow keys.
-   `tabToNextHeader` uses tabbing to go up and down rather than right and left.
-   When a cell in the first grid row is focused, pressing the down arrow will navigate to the header by passing `rowIndex: -1`.
-   When a header cell in the last header row is focused, pressing the up arrow will navigate to the first grid row by passing `headerRowIndex: -1`.
-   Tabbing/Shift tabbing will move the focus until the first header or the last grid row, but focus will not leave the grid.

{% gridExampleRunner title="Custom Keyboard Navigation" name="custom-keyboard-navigation" /%}

## Custom Master Detail Navigation

[Master Detail Grids](./master-detail/) can contain [Custom Details](./master-detail-custom-detail/) that have their own renderer and hence will need to implement its own keyboard navigation. An example of this can be seen in the [Custom Details Keyboard Navigation Example](./master-detail-custom-detail/#keyboard-navigation).

## Tabbing into the Grid

In applications where the grid is embedded into a larger page, by default, when tabbing into the grid, the first column header will be focused.

You could override this behaviour to focus the first grid cell, if that is a preferred scenario using a combination of DOM event listeners and Grid API calls shown in the following code snippet:

```{% frameworkTransform=true %}
// obtain reference to input element
const myInput = document.getElementById("my-input");

// intercept key strokes within input element
myInput.addEventListener("keydown", event => {
    // ignore non tab key strokes
    if (event.key !== 'Tab') return;

    // prevents tabbing into the url section
    event.preventDefault();

    // scrolls to the first row
    gridApi.ensureIndexVisible(0);

    // scrolls to the first column
    const firstCol = api.getAllDisplayedColumns()[0];
    gridApi.ensureColumnVisible(firstCol);

    // sets focus into the first grid cell
    gridApi.setFocusedCell(0, firstCol);

}, true);
```

### Tabbing into the Grid

In the following example there are two input box provided to test tabbing into the grid. Notice the following:

-   Tabbing out of the input above the grid will focus the first grid header.
-   When the first cell is out of view due to either scrolling down (rows) or across (columns), the grid will scroll back to the left to display the first column.
-   Tabbing out of the input below the grid with shift pressed will focus the last cell of the grid.
-   When the last column is out of view due to horizontal scroll, shift tabbing into the grid will cause the grid to scroll to focus the last cell.

{% gridExampleRunner title="Tabbing into the Grid" name="tabbing-into-grid" /%}

### Custom Tabbing into the Grid

The `focusGridInnerElement` callback can be used to change the element focused by the grid when receiving focus from outside . Notice the following:

-   Tabbing out of the input above the grid will focus the last focused cell if the grid was previously focused and the element is still in the DOM or otherwise the header.
-   Shift Tabbing out of the input below the grid will focus the last focused cell if the grid was previously focused and the element is still in the DOM or otherwise the last cell in the bottom row.

{% gridExampleRunner title="Custom tabbing into the Grid" name="custom-tabbing-into-grid" /%}

## Keyboard Events

It is possible to add custom behaviour to any key event that you want using the grid events `cellKeyDown` (gets called when a DOM `keyDown` event fires on a cell).

{% note %}
These keyboard events are monitored by the grid panel, so they will not be fired
when the `keydown` happens inside of a popup editor, as popup elements are
rendered in a different DOM tree.
{% /note %}

The grid events wrap the DOM events and provides additional information such as row and column details.

The example below shows processing grid cell keyboard events. The following can be noted:

-   Each time a `cellKeyDown` is fired, the details of the event are logged to the console.
-   When the user hits {% kbd "S" /%} on a row, the row selection is toggled.

{% gridExampleRunner title="Keyboard Events" name="keyboard-events" /%}

## Suppress Keyboard Events

It is possible to stop the grid acting on particular events. To do this implement `colDef.suppressHeaderKeyboardEvent` and/or `colDef.suppressKeyboardEvent` callback. The callback should return `true` if the grid should suppress the events, or `false` to continue as normal.

### suppressHeaderKeyboardEvent

{% apiDocumentation source="column-properties/properties.json" section="header" names=["suppressHeaderKeyboardEvent"] /%}

### suppressKeyboardEvent

{% apiDocumentation source="column-properties/properties.json" section="columns" names=["suppressKeyboardEvent"] /%}

The callback is available as a [column callback](./column-properties/#reference-columns-suppressKeyboardEvent) (set on the column definition). If you want it to apply to all columns then apply to the `defaultColDef` property.

### Example: Suppress Keyboard Navigation

The example below demonstrates suppressing the following keyboard events:

-   On the Athlete column cells only:
    -   {% kbd "↵ Enter" /%} will not start or stop editing.
-   On the Country column cells only:
    -   {% kbd "↑" /%} {% kbd "↓" /%} arrow keys are allowed. This is the only column that allows navigation from the grid to the header.
-   On all cells (including the cells of the Athlete Column):
    -   {% kbd "^ Ctrl" /%}+{% kbd "A" /%} will not select all cells into a range.
    -   {% kbd "^ Ctrl" /%}+{% kbd "C" /%} will not copy to clipboard.
    -   {% kbd "^ Ctrl" /%}+{% kbd "V" /%} will not paste from clipboard.
    -   {% kbd "^ Ctrl" /%}+{% kbd "D" /%} will not copy range down.
    -   {% kbd "Page Up" /%} and {% kbd "Page Down" /%} will not get handled by the grid.
    -   {% kbd "Home" /%} will not focus top left cell.
    -   {% kbd "End" /%} will not focus bottom right cell.
    -   {% kbd "←" /%} {% kbd "↑" /%} {% kbd "→" /%} {% kbd "↓" /%} Arrow keys will not navigate focused cell.
    -   {% kbd "F2" /%} will not start editing.
    -   {% kbd "Delete" /%} will not start editing.
    -   {% kbd "⌫ Backspace" /%} will not start editing.
    -   {% kbd "⎋ Escape" /%} will not cancel editing.
    -   {% kbd "␣ Space" /%} will not select current row.
    -   {% kbd "⇥ Tab" /%} will not be handled by the grid.
-   On the Country header only:
    -   Navigation is blocked from the left to right using arrows but is allowed using {% kbd "⇥ Tab" /%}.
    -   Navigation up and down is allowed. This is the only header that allows navigation from the header to the grid cells.
    -   {% kbd "↵ Enter" /%} is blocked. This is the only header that blocks sorting / opening menu via keyboard.
-   On all headers (excluding country):
    -   Navigation is blocked up and down, but navigation left / right is allowed using arrows and {% kbd "⇥ Tab" /%}.

{% gridExampleRunner title="Suppress Keys" name="suppress-keys" /%}

## Custom Cell Component

When using custom Cell Components, the custom Cell Component is responsible for implementing support for keyboard navigation among its focusable elements. This is why by default, focusing a grid cell with a custom Cell Component will focus the entire cell instead of any of the elements inside the custom cell renderer.

Adding support for keyboard navigation and focus requires a custom `suppressKeyboardEvent` function in grid options. See [Suppress Keyboard Events](./keyboard-navigation/#suppress-keyboard-events).

An example of this is shown below, enabling keyboard navigation through the custom cell elements when pressing {% kbd "⇥ Tab" /%} and {% kbd "⇧ Shift" /%}+{% kbd "⇥ Tab" /%}:

-   Click on the top left `Natalie Coughlin` cell, press the {% kbd "⇥ Tab" /%} key and notice that the button, textbox and link can be tabbed into. At the end of the cell elements, the tab focus moves to the next cell in the next row
-   Use {% kbd "⇧ Shift" /%}+{% kbd "⇥ Tab" /%} to navigate in the reverse direction

The `suppressKeyboardEvent` callback is used to capture tab events and determine if the user is tabbing forward or backwards. It also suppresses the default behaviour of moving to the next cell if tabbing within the child elements.

If the focus is at the beginning or the end of the cell children and moving out of the cell, the keyboard event is not suppressed, so focus can move between the children elements. Also, when moving backwards, the focus needs to be manually set while preventing the default behaviour of the keyboard press event.

{% gridExampleRunner title="Cell Renderer Keyboard Navigation" name="cell-renderer-keyboard-navigation" /%}
